﻿using System;
using System.Collections.Generic;
using Character;
using IllusionUtility.GetUtility;
using WzhAddon.DHHPlugIn;
using RootMotion.FinalIK;
using Studio;
using UnityEngine;

namespace WzhAddon
{
	public class IKMorphFix : MonoBehaviour
	{
		private static string[] boneNames = new string[]
	{
			"_J_ArmUp00_",
			"_J_ArmLow01_",
			"_J_ArmElbo_dam_01_",
			"_J_ArmElbo_dam_02_",
			"_J_ArmElboura_dam_",
			"_J_Hand_",
			"_J_LegUp00_",
			"_J_LegLow01_",
			"_J_Foot01_",
			"_J_LegUp01_",
			"_J_LegKnee_back_",
			"_J_LegKnee_back_s_",
			"_J_LegKnee_dam_"
	};

		public bool dhhEnable = true;
		private IKSolverFullBodyBiped solver;
		private Dictionary<string, Transform> bonesTrans;
		public Transform FeetBaseL;
		public Transform FeetBaseR;
		public Transform FeetL;
		public Transform FeetR;
		public Transform ToeL;
		public Transform ToeR;
		public bool fixEnabled;
		public bool makeSmall;
		public bool fix3Enabled;
		public bool debugEnabled;
		public float smallKneeBackScale = 0.116f;
		public float smallElboBackScale = 0.385f;
		private Dictionary<string, Vector3> prePos;
		private Dictionary<string, Quaternion> preRot;
	
		public static float up01RotX = 0f;
		public static float up01RotY = 0f;
		public static float up01RotZ = 0f;
		public static float up01X = 0f;
		public static float up01Y = 0f;
		public static float up01Z = 0f;
		private static float elboUraAngleS = 180f;
		private static float elboUraAngleE = 180f;
		private static float elboUraLen = -0.02f;
		private static float elboUraLenE = -0.07f;
		private static float elboUraRotX = 0f;
		private static float elboUraRotY = 0f;
		private static float elboUraRotZ = 0f;
		private static float elboAngleS = 90f;
		private static float elboAngleE = 120f;
		private static float elboLen = 0.01f;
		private static float elboLenE = 0.02f;
		private static float elboRotX = 10f;
		private static float elboRotY = 0f;
		private static float elboRotZ = 0f;
		private static float kneeAngleS = 70f;
		private static float kneeAngleE = 130f;
		private static float kneeLen = 0.025f;
		private static float kneeLenE = 0.025f;
		private static float kneeRotX = 0f;
		private static float kneeRotY = 0f;
		private static float kneeRotZ = -20f;
		private static float kneeBackAngleS = 180f;
		private static float kneeBackAngleE = 180f;
		private static float kneeBackLen = -0.15f;
		private static float kneeBackRotX = 0f;
		private static float kneeBackRotY = 0f;
		private static float kneeBackRotZ = 0f;
		private List<IKMorphFix.LinkRotation> linkRotations = new List<IKMorphFix.LinkRotation>();
		public OCIChar studioChara { get; private set; }
		public string BoneInfo1 { get { return this.GetIKBoneInfo(); } }
		public static IKMorphFix Install(OCIChar studioChara)
		{
			IKMorphFix ikmorphFix = studioChara.charInfo.gameObject.AddComponent<IKMorphFix>();
			ikmorphFix.Init(studioChara);
			return ikmorphFix;
		}
		private void Init(OCIChar studioChara)
		{
			this.studioChara = studioChara;
			this.solver = studioChara.fullBodyIK.solver;
			this.solver.OnPreUpdate = new IKSolver.UpdateDelegate(this.OnPreUpdate);
			this.solver.OnPostUpdate = new IKSolver.UpdateDelegate(this.OnPostUpdate);
			this.InitFix3Parameters();
			this.InitDHHBones(studioChara);
		}
		public static IKMorphFix Get(ChaControl charInfo)
		{
			return charInfo.gameObject.GetComponent<IKMorphFix>();
		}
		private void InitDHHBones(OCIChar studioChara)
		{
			if (studioChara.charInfo.sex == 1)
			{
				Transform transform = studioChara.charInfo.objBodyBone.transform;
				this.FeetBaseL = transform.Find("BodyTop/p_cf_anim/cf_J_Root/cf_N_height/cf_J_Hips/cf_J_Kosi01/cf_J_Kosi02/cf_J_LegUp00_L/cf_J_LegLow01_L/cf_J_LegLowRoll_L/cf_J_Foot01_L");
				this.FeetBaseR = transform.Find("BodyTop/p_cf_anim/cf_J_Root/cf_N_height/cf_J_Hips/cf_J_Kosi01/cf_J_Kosi02/cf_J_LegUp00_R/cf_J_LegLow01_R/cf_J_LegLowRoll_R/cf_J_Foot01_R");
				this.FeetL = transform.Find("BodyTop/p_cf_anim/cf_J_Root/cf_N_height/cf_J_Hips/cf_J_Kosi01/cf_J_Kosi02/cf_J_LegUp00_L/cf_J_LegLow01_L/cf_J_LegLowRoll_L/cf_J_Foot01_L/cf_J_Foot02_L");
				this.FeetR = transform.Find("BodyTop/p_cf_anim/cf_J_Root/cf_N_height/cf_J_Hips/cf_J_Kosi01/cf_J_Kosi02/cf_J_LegUp00_R/cf_J_LegLow01_R/cf_J_LegLowRoll_R/cf_J_Foot01_R/cf_J_Foot02_R");
				this.ToeL = transform.Find("BodyTop/p_cf_anim/cf_J_Root/cf_N_height/cf_J_Hips/cf_J_Kosi01/cf_J_Kosi02/cf_J_LegUp00_L/cf_J_LegLow01_L/cf_J_LegLowRoll_L/cf_J_Foot01_L/cf_J_Foot02_L/cf_J_Toes01_L");
				this.ToeR = transform.Find("BodyTop/p_cf_anim/cf_J_Root/cf_N_height/cf_J_Hips/cf_J_Kosi01/cf_J_Kosi02/cf_J_LegUp00_R/cf_J_LegLow01_R/cf_J_LegLowRoll_R/cf_J_Foot01_R/cf_J_Foot02_R/cf_J_Toes01_R");
				this.FeetBaseL = TransformFindEx.FindLoop(transform, "cf_J_Foot01_L").transform;
				this.FeetBaseR = TransformFindEx.FindLoop(transform, "cf_J_Foot01_R").transform;
				this.FeetL = TransformFindEx.FindLoop(transform, "cf_J_Foot02_L").transform;
				this.FeetR = TransformFindEx.FindLoop(transform, "cf_J_Foot02_R").transform;
				this.ToeL = TransformFindEx.FindLoop(transform, "cf_J_Toes01_L").transform;
				this.ToeR = TransformFindEx.FindLoop(transform, "cf_J_Toes01_R").transform;
			}
		}
		private void OnPreUpdate()
		{
			if (this.debugEnabled)
			{
				Console.WriteLine("On Pre Update");
			}
			this.prePos = new Dictionary<string, Vector3>();
			this.preRot = new Dictionary<string, Quaternion>();
			if (this.bonesTrans == null)
			{
				this.bonesTrans = this.GetLegBones(this.studioChara.charInfo.objBodyBone.transform);
				this.InitDHHBones(this.studioChara);
			}
			foreach (string key in this.bonesTrans.Keys)
			{
				Transform transform = this.bonesTrans[key];
				this.prePos[key] = transform.position;
				this.preRot[key] = transform.rotation;
			}
		}
		private void OnPostUpdate()
		{
			if (this.debugEnabled)
			{
				Console.WriteLine("On Post Update");
			}
			if (this.bonesTrans == null)
			{
				this.bonesTrans = this.GetLegBones(this.studioChara.charInfo.objBodyBone.transform);
				this.InitDHHBones(this.studioChara);
			}
			foreach (string text in this.bonesTrans.Keys)
			{
				Transform transform = this.bonesTrans[text];
				Vector3 vector = transform.position - this.prePos[text];
				Quaternion quaternion = transform.rotation * Quaternion.Inverse(this.preRot[text]);
				if (this.debugEnabled)
				{
					Console.WriteLine("Bone pos: {0} - {1} - ({2}, {3}, {4})", new object[]
					{
						text,
						vector == Vector3.zero,
						vector.x,
						vector.y,
						vector.z
					});
					Console.WriteLine("Bone rot: {0} - {1} - (w: {2}, x: {3}, y: {4}, z: {5})", new object[]
					{
						text,
						quaternion == Quaternion.identity,
						quaternion.w,
						quaternion.x,
						quaternion.y,
						quaternion.z
					});
				}
			}
			string[] array = new string[] { "L", "R" };
			bool flag = false;
			string str;
			if (this.studioChara is OCICharMale)
			{
				str = "cm";
				flag = true;
			}
			else
			{
				if (!(this.studioChara is OCICharFemale)) return;
				str = "cf";
			}
			if (this.fixEnabled && !this.makeSmall)
			{
				foreach (string str2 in array)
				{
					string key = str + "_J_LegUp00_" + str2;
					string key2 = str + "_J_LegLow01_" + str2;
					string key3 = str + "_J_Foot01_" + str2;
					string text2 = str + "_J_LegUp01_" + str2;
					string text3 = str + "_J_LegKnee_dam_" + str2;
					string text4 = str + "_J_LegKnee_back_" + str2;
					if (flag) text4 = str + "_J_LegKnee_back_s_" + str2;
					Transform transform2 = this.bonesTrans[key];
					Transform transform3 = this.bonesTrans[key2];
					Transform transform4 = this.bonesTrans[key3];
					Vector3 vector2 = this.prePos[key];
					Vector3 vector3 = this.prePos[key2];
					Vector3 vector4 = this.prePos[key3];
					new Plane(vector2, vector3, vector4);
					Plane plane=new Plane(transform2.position, transform3.position, transform4.position);
					Vector3 normalized = (transform2.transform.position - transform3.transform.position).normalized;
					Vector3 normalized2 = (transform4.transform.position - transform3.transform.position).normalized;
					float num = Vector3.Angle(normalized, normalized2);
					float num2 = 1f - num / 180f;
					string key4 = text2;
					Transform transform5 = this.bonesTrans[key4];
					Vector3 vector5 = this.prePos[key4];
					Quaternion quaternion2 = this.preRot[key4];
					transform5.position += transform2.TransformVector(IKMorphFix.up01X, IKMorphFix.up01Y, IKMorphFix.up01Z);
					transform5.rotation = Quaternion.Euler(IKMorphFix.up01RotX, IKMorphFix.up01RotY, IKMorphFix.up01RotZ) * transform2.transform.rotation;
					string key5 = text4;
					Transform transform6 = this.bonesTrans[key5];
					Vector3 vector6 = this.prePos[key5];
					Quaternion quaternion3 = this.preRot[key5];
					float num3 = 0f;
					float num4 = IKMorphFix.kneeBackLen;
					float num5 = Mathf.Lerp(IKMorphFix.kneeBackAngleS, IKMorphFix.kneeBackAngleE, num2);
					Vector3 vector7 = Vector3.RotateTowards(normalized, normalized2, -1f * num5 * 0.017453292f, 0f);
					vector7.x *= transform2.transform.lossyScale.x;
					vector7.y *= transform2.transform.lossyScale.y;
					vector7.z *= transform2.transform.lossyScale.z;
					transform6.position = transform3.transform.position + vector7.normalized * num4 + plane.normal * num3;
					transform6.rotation = Quaternion.Euler(IKMorphFix.kneeBackRotX, IKMorphFix.kneeBackRotY, IKMorphFix.kneeBackRotZ) * transform3.rotation;
					string key6 = text3;
					Transform transform7 = this.bonesTrans[key6];
					Vector3 vector8 = this.prePos[key6];
					Quaternion quaternion4 = this.preRot[key6];
					float num6 = 0f;
					float num7 = Mathf.Lerp(IKMorphFix.kneeAngleS, IKMorphFix.kneeAngleE, num2);
					float num8 = Mathf.Lerp(IKMorphFix.kneeLen, IKMorphFix.kneeLenE, num2);
					Vector3 vector9 = Vector3.RotateTowards(normalized, normalized2, -1f * num7 * 0.017453292f, 0f);
					vector9.x *= transform2.transform.lossyScale.x;
					vector9.y *= transform2.transform.lossyScale.y;
					vector9.z *= transform2.transform.lossyScale.z;
					transform7.position = transform3.transform.position + vector9.normalized * num8 + plane.normal * num6;
					transform7.rotation = Quaternion.Euler(IKMorphFix.kneeRotX, IKMorphFix.kneeRotY, IKMorphFix.kneeRotZ) * transform3.rotation;
					string key7 = str + "_J_ArmUp00_" + str2;
					string key8 = str + "_J_ArmLow01_" + str2;
					string key9 = str + "_J_Hand_" + str2;
					string text5 = str + "_J_ArmElbo_dam_01_" + str2;
					if (flag) text5 = str + "_J_ArmElbo_dam_02_" + str2;
					string text6 = str + "_J_ArmElboura_dam_" + str2;
					Transform transform8 = this.bonesTrans[key7];
					Transform transform9 = this.bonesTrans[key8];
					Transform transform10 = this.bonesTrans[key9];
					Vector3 vector10 = this.prePos[key7];
					Vector3 vector11 = this.prePos[key8];
					Vector3 vector12 = this.prePos[key9];
					new Plane(vector10, vector11, vector12);
					Plane plane2=new Plane(transform8.position, transform9.position, transform10.position);
					Vector3 normalized3 = (transform8.transform.position - transform9.transform.position).normalized;
					Vector3 normalized4 = (transform10.transform.position - transform9.transform.position).normalized;
					float num9 = Vector3.Angle(normalized3, normalized4);
					float num10 = 1f - num9 / 180f;
					string key10 = text5;
					Transform transform11 = this.bonesTrans[key10];
					Vector3 vector13 = this.prePos[key10];
					Quaternion quaternion5 = this.preRot[key10];
					float num11 = 0f;
					float num12 = Mathf.Lerp(IKMorphFix.elboAngleS, IKMorphFix.elboAngleE, num10);
					float num13 = Mathf.Lerp(IKMorphFix.elboLen, IKMorphFix.elboLenE, num10);
					Vector3 vector14 = Vector3.RotateTowards(normalized3, normalized4, -1f * num12 * 0.017453292f, 0f);
					vector14.x *= transform8.transform.lossyScale.x;
					vector14.y *= transform8.transform.lossyScale.y;
					vector14.z *= transform8.transform.lossyScale.z;
					transform11.position = transform9.transform.position + vector14.normalized * num13 + plane2.normal * num11;
					transform11.rotation = Quaternion.Euler(IKMorphFix.elboRotX, IKMorphFix.elboRotY, IKMorphFix.elboRotZ) * transform9.rotation;
					string key11 = text6;
					Transform transform12 = this.bonesTrans[key11];
					Vector3 vector15 = this.prePos[key11];
					Quaternion quaternion6 = this.preRot[key11];
					float num14 = 0f;
					float num15 = Mathf.Lerp(IKMorphFix.elboUraAngleS, IKMorphFix.elboUraAngleE, num10);
					float num16 = Mathf.Lerp(IKMorphFix.elboUraLen, IKMorphFix.elboUraLenE, num10);
					Vector3 vector16 = Vector3.RotateTowards(normalized3, normalized4, -1f * num15 * 0.017453292f, 0f);
					vector16.x *= transform8.transform.lossyScale.x;
					vector16.y *= transform8.transform.lossyScale.y;
					vector16.z *= transform8.transform.lossyScale.z;
					transform12.position = transform9.transform.position + vector16.normalized * num16 + plane2.normal * num14;
					transform12.rotation = Quaternion.Euler(IKMorphFix.elboUraRotX, IKMorphFix.elboUraRotY, IKMorphFix.elboUraRotZ) * transform9.rotation;
				}
			}
			else
			{
				foreach (string str3 in new string[] { "L", "R" })
				{
					//str + "_J_LegKnee_dam_" + str3;
					string key12 = str + "_J_LegKnee_back_" + str3;
					if (flag)
					{
						key12 = str + "_J_LegKnee_back_s_" + str3;
					}
					string key13 = str + "_J_ArmElboura_dam_" + str3;
					Transform transform13 = this.bonesTrans[key12];
					Transform transform14 = this.bonesTrans[key13];
					if (this.makeSmall)
					{
						transform13.localScale = new Vector3(transform13.localScale.x, this.smallKneeBackScale, transform13.localScale.z);
						transform14.localScale = new Vector3(transform14.localScale.x, this.smallElboBackScale, transform14.localScale.z);
					}
					else
					{
						transform13.localScale = new Vector3(transform13.localScale.x, transform13.localScale.x, transform13.localScale.z);
						transform14.localScale = new Vector3(transform14.localScale.x, transform14.localScale.x, transform14.localScale.z);
					}
				}
			}
			if (this.fix3Enabled)
			{
				this.DoFix3();
			}
		}

		public void UpdateDhh()
		{
			if (this.dhhEnable && this.studioChara.charInfo.human.wears.GetShow(WEAR_SHOW_TYPE.SHOES, true) != WEAR_SHOW.HIDE)
			{
				int id = this.studioChara.charInfo.human.wears.GetWearData(WEAR_TYPE.SHOES).id;
				if (BaseMgr<HighHeelRunTime>.Instance.ShoeDataMap.ContainsKey(id))
				{
					ShoeFixData shoeFixData = BaseMgr<HighHeelRunTime>.Instance.ShoeDataMap[id];
					if (shoeFixData.FeetBaseRotOffset != 0f || shoeFixData.FeetBaseRollOffset != 0f)
					{
						Vector3 localEulerAngles = this.FeetBaseL.transform.localEulerAngles;
						Vector3 localEulerAngles2 = this.FeetBaseR.transform.localEulerAngles;
						localEulerAngles.x = HighHeelRunTime.FormatAngle(localEulerAngles.x, shoeFixData.FeetBaseRotOffset, shoeFixData.FeetBaseRotOffset - 21f, 23f);
						localEulerAngles2.x = HighHeelRunTime.FormatAngle(localEulerAngles2.x, shoeFixData.FeetBaseRotOffset, shoeFixData.FeetBaseRotOffset - 21f, 23f);
						localEulerAngles.y += shoeFixData.FeetBaseRollOffset;
						localEulerAngles2.y -= shoeFixData.FeetBaseRollOffset;
						this.FeetBaseL.transform.localEulerAngles = localEulerAngles;
						this.FeetBaseR.transform.localEulerAngles = localEulerAngles2;
					}
					if (shoeFixData.FeetRotOffset != 0f)
					{
						Vector3 localEulerAngles3 = this.FeetL.transform.localEulerAngles;
						Vector3 localEulerAngles4 = this.FeetR.transform.localEulerAngles;
						localEulerAngles3.x = HighHeelRunTime.FormatAngle(localEulerAngles3.x, shoeFixData.FeetRotOffset, shoeFixData.FeetRotOffset - 15f, 22f);
						localEulerAngles4.x = HighHeelRunTime.FormatAngle(localEulerAngles4.x, shoeFixData.FeetRotOffset, shoeFixData.FeetRotOffset - 15f, 22f);
						this.FeetL.transform.localEulerAngles = localEulerAngles3;
						this.FeetR.transform.localEulerAngles = localEulerAngles4;
					}
					this.FeetL.transform.localScale = new Vector3(shoeFixData.FeetWidth, 1f, 1f);
					this.FeetR.transform.localScale = new Vector3(shoeFixData.FeetWidth, 1f, 1f);
					if (shoeFixData.ToeRotOffset != 0f)
					{
						Vector3 localEulerAngles5 = this.ToeL.transform.localEulerAngles;
						Vector3 localEulerAngles6 = this.ToeR.transform.localEulerAngles;
						localEulerAngles5.x = HighHeelRunTime.FormatAngle(localEulerAngles5.x, shoeFixData.ToeRotOffset, -shoeFixData.ToeRotOffset + 3f, -shoeFixData.ToeRotOffset - 6f);
						localEulerAngles6.x = HighHeelRunTime.FormatAngle(localEulerAngles6.x, shoeFixData.ToeRotOffset, -shoeFixData.ToeRotOffset + 3f, -shoeFixData.ToeRotOffset - 6f);
						this.ToeL.transform.localEulerAngles = localEulerAngles5;
						this.ToeR.transform.localEulerAngles = localEulerAngles6;
					}
					this.ToeL.transform.localScale = new Vector3(shoeFixData.ToeWidth, shoeFixData.ToeThickness, shoeFixData.ToeLength);
					this.ToeR.transform.localScale = new Vector3(shoeFixData.ToeWidth, shoeFixData.ToeThickness, shoeFixData.ToeLength);
				}
			}
		}

		private void LateUpdate()
		{
			this.UpdateDhh();
		}
		public string GetIKBoneInfo()
		{
			string str = "";
			if (this.studioChara is OCICharMale) str = "cm";
			else if (this.studioChara is OCICharFemale) str = "cf";
			Transform transform = this.studioChara.charInfo.objBodyBone.transform;
			string[] array = new string[]{"L"};
			int num = 0;
			if (num >= array.Length) return "";
			string str2 = array[num];
			Transform transform2 = TransformFindEx.FindLoop(transform, str + "_J_Hips").transform;
			Transform transform3 = TransformFindEx.FindLoop(transform, str + "_J_Kosi01").transform;
			Transform transform4 = TransformFindEx.FindLoop(transform, str + "_J_LegUp01_s_" + str2).transform;
			Transform transform5 = TransformFindEx.FindLoop(transform, str + "_J_LegUpDam_" + str2).transform;
			Transform transform6 = TransformFindEx.FindLoop(transform, str + "_J_SiriDam_" + str2).transform;
			Vector3 normalizedRot = this.GetNormalizedRot(Quaternion.Inverse(transform3.rotation) * transform4.rotation);
			Vector3 normalizedRot2 = this.GetNormalizedRot(Quaternion.Inverse(transform3.rotation) * transform5.rotation);
			Vector3 normalizedRot3 = this.GetNormalizedRot(Quaternion.Inverse(transform3.rotation) * transform6.rotation);
			Vector3 normalizedRot4 = this.GetNormalizedRot(Quaternion.Inverse(transform2.rotation) * transform4.rotation);
			Vector3 normalizedRot5 = this.GetNormalizedRot(Quaternion.Inverse(transform2.rotation) * transform5.rotation);
			Vector3 normalizedRot6 = this.GetNormalizedRot(Quaternion.Inverse(transform2.rotation) * transform6.rotation);
			return string.Format("{0}\t{3}\r\n{1}\t{4}\r\n{2}\t{5}\r\n", new object[]
			{
				normalizedRot,
				normalizedRot2,
				normalizedRot3,
				normalizedRot4,
				normalizedRot5,
				normalizedRot6
			});
		}

		private Vector3 GetAdjustedRot(Vector3 rot, Vector3 a)
		{
			return new Vector3(rot.x * a.x, rot.y * a.y, rot.z * a.z);
		}

		private Vector3 GetNormalizedRot(Quaternion q)
		{
			Vector3 eulerAngles = q.eulerAngles;
			if (eulerAngles.x >= 180f) eulerAngles.x -= 360f;
			if (eulerAngles.y >= 180f) eulerAngles.y -= 360f;
			if (eulerAngles.z >= 180f) eulerAngles.z -= 360f;
			return eulerAngles;
		}

		private Dictionary<string, Transform> GetBones()
		{
			Transform transform = this.studioChara.charInfo.objBodyBone.transform;
			return this.GetLegBones(transform);
		}

		private Dictionary<string, Transform> GetLegBones(Transform root)
		{
			string str = "cf";
			if (this.studioChara is OCICharFemale) str = "cf";
			else if (this.studioChara is OCICharMale) str = "cm";
			Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>();
			foreach (string str2 in IKMorphFix.boneNames)
			{
				try
				{
					dictionary.Add(str + str2 + "L", TransformFindEx.FindLoop(root, str + str2 + "L").transform);
					dictionary.Add(str + str2 + "R", TransformFindEx.FindLoop(root, str + str2 + "R").transform);
				}
				catch (Exception)
				{
				}
			}
			return dictionary;
		}

		private void InitFix3Parameters()
		{
			string str = "cf_";
			if (this.studioChara is OCICharMale) str = "cm_";
			this.AddLinkRotation(str + "J_LegUp00_R", str + "J_LegUpDam_R", 0.8f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			this.AddLinkRotation(str + "J_LegLow01_R", str + "J_LegKnee_dam_R", 0.5f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			this.AddLinkRotation(str + "J_LegUp00_L", str + "J_LegUpDam_L", 0.8f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			this.AddLinkRotation(str + "J_LegLow01_L", str + "J_LegKnee_dam_L", 0.5f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			this.AddLinkRotation(str + "J_Hand_R", str + "J_Hand_Wrist_dam_R", 1f, IKMorphFix.LinkRotation.LinkRotationType.WRIST_DAM);
			this.AddLinkRotation(str + "J_Hand_R", str + "J_ArmLow02_dam_R", 1f, IKMorphFix.LinkRotation.LinkRotationType.ARMLOW02_DAM);
			this.AddLinkRotation(str + "J_ArmUp00_R", str + "J_ArmUp01_dam_R", 1f, IKMorphFix.LinkRotation.LinkRotationType.ARM01_DAM);
			this.AddLinkRotation(str + "J_ArmLow01_R", str + "J_ArmElboura_dam_R", 0.75f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			this.AddLinkRotation(str + "J_Hand_L", str + "J_Hand_Wrist_dam_L", -1f, IKMorphFix.LinkRotation.LinkRotationType.WRIST_DAM);
			this.AddLinkRotation(str + "J_Hand_L", str + "J_ArmLow02_dam_L", 1f, IKMorphFix.LinkRotation.LinkRotationType.ARMLOW02_DAM);
			this.AddLinkRotation(str + "J_ArmUp00_L", str + "J_ArmUp01_dam_L", 1f, IKMorphFix.LinkRotation.LinkRotationType.ARM01_DAM);
			this.AddLinkRotation(str + "J_ArmLow01_L", str + "J_ArmElboura_dam_L", 0.75f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			if (this.studioChara is OCICharMale)
			{
				this.AddLinkRotation(str + "J_ArmLow01_R", str + "J_ArmElbo_dam_02_R", -1f, IKMorphFix.LinkRotation.LinkRotationType.ARMLOW01_ELBO_DAM);
				this.AddLinkRotation(str + "J_ArmLow01_L", str + "J_ArmElbo_dam_02_L", 1f, IKMorphFix.LinkRotation.LinkRotationType.ARMLOW01_ELBO_DAM);
				return;
			}
			this.AddLinkRotation(str + "J_LegLow01_R", str + "J_LegKnee_back_R", 1f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			this.AddLinkRotation(str + "J_LegLow01_L", str + "J_LegKnee_back_L", 1f, IKMorphFix.LinkRotation.LinkRotationType.DEFAULT);
			this.AddLinkRotation(str + "J_ArmLow01_R", str + "J_ArmElbo_dam_01_R", -1f, IKMorphFix.LinkRotation.LinkRotationType.ARMLOW01_ELBO_DAM);
			this.AddLinkRotation(str + "J_ArmLow01_L", str + "J_ArmElbo_dam_01_L", 1f, IKMorphFix.LinkRotation.LinkRotationType.ARMLOW01_ELBO_DAM);
		}

		private void AddLinkRotation(string baseBoneName, string linkBoneName, float linkRate, IKMorphFix.LinkRotation.LinkRotationType linkType = IKMorphFix.LinkRotation.LinkRotationType.DEFAULT)
		{
			GameObject gameObject = TransformFindEx.FindLoop(this.studioChara.charInfo.transform, baseBoneName);
			GameObject gameObject2 = TransformFindEx.FindLoop(this.studioChara.charInfo.transform, linkBoneName);
			if (gameObject == null)
			{
				Console.WriteLine(baseBoneName + " not found");
				return;
			}
			if (gameObject2 == null)
			{
				Console.WriteLine(linkBoneName + " not found");
				return;
			}
			IKMorphFix.LinkRotation linkRotation = new IKMorphFix.LinkRotation(linkType);
			linkRotation.baseBone = gameObject.transform;
			linkRotation.linkBone = gameObject2.transform;
			linkRotation.linkRate = linkRate;
			this.linkRotations.Add(linkRotation);
		}

		public void DoFix3()
		{
			if (this.linkRotations != null)
			{
				foreach (IKMorphFix.LinkRotation linkRotation in this.linkRotations)
				{
					linkRotation.DoUpdate();
				}
			}
		}

		
		private class LinkRotation
		{
			public LinkRotation(IKMorphFix.LinkRotation.LinkRotationType type = IKMorphFix.LinkRotation.LinkRotationType.DEFAULT)
			{
				if (type == IKMorphFix.LinkRotation.LinkRotationType.DEFAULT)
				{
					this.DoUpdate = new Action(this.DefaultDoUpdate);
					return;
				}
				if (type == IKMorphFix.LinkRotation.LinkRotationType.ARM01_DAM)
				{
					this.DoUpdate = new Action(this.ArmUp01DamDoUpdate);
					return;
				}
				if (type == IKMorphFix.LinkRotation.LinkRotationType.ARMLOW01_ELBO_DAM)
				{
					this.DoUpdate = new Action(this.ArmLow01ElboDamDoUpdate);
					return;
				}
				if (type == IKMorphFix.LinkRotation.LinkRotationType.ARMLOW02_DAM)
				{
					this.DoUpdate = new Action(this.ArmLow02DamDoUpdate);
					return;
				}
				if (type == IKMorphFix.LinkRotation.LinkRotationType.WRIST_DAM)
				{
					this.DoUpdate = new Action(this.WristDamDoUpdate);
				}
			}

			public void DefaultDoUpdate()
			{
				if (this.baseBone != null && this.linkBone != null)
				{
					this.linkBone.localRotation = Quaternion.Slerp(Quaternion.identity, this.baseBone.localRotation, this.linkRate);
				}
			}

			public void ArmUp01DamDoUpdate()
			{
				if (this.baseBone != null && this.linkBone != null)
				{
					float num = this.Normalize(this.baseBone.localEulerAngles.x, 180f);
					float num2 = this.Normalize(this.baseBone.localEulerAngles.y, 180f);
					float z = this.baseBone.localEulerAngles.z;
					float num3 = -0.85f * num + -0.16f * num2 + -0.06f * z;
					this.linkBone.localEulerAngles = new Vector3(num3, 0f, 0f);
				}
			}

			public void ArmLow02DamDoUpdate()
			{
				if (this.baseBone != null && this.linkBone != null)
				{
					float num = this.Normalize(this.baseBone.localEulerAngles.x, 180f);
					this.Normalize(this.baseBone.localEulerAngles.y, 180f);
					this.Normalize(this.baseBone.localEulerAngles.z, 180f);
					float num2 = 0.5f * num;
					this.linkBone.localEulerAngles = new Vector3(num2, 0f, 0f);
				}
			}

			public void WristDamDoUpdate()
			{
				if (this.baseBone != null && this.linkBone != null)
				{
					float num = this.Normalize(this.baseBone.localEulerAngles.x, 180f);
					this.Normalize(this.baseBone.localEulerAngles.y, 180f);
					float num2 = this.Normalize(this.baseBone.localEulerAngles.z, 180f);
					float num3 = (1f + this.linkRate * 0.016f) * num + this.linkRate * 0.1f * num2;
					this.linkBone.localEulerAngles = new Vector3(num3, 0f, 0f);
				}
			}

			public void ArmLow01ElboDamDoUpdate()
			{
				if (this.baseBone != null && this.linkBone != null)
				{
					this.Normalize(this.baseBone.localEulerAngles.x, 180f);
					float num = this.Normalize(this.baseBone.localEulerAngles.y, 180f);
					this.Normalize(this.baseBone.localEulerAngles.z, 180f);
					float num2 = this.linkRate * -0.27496174f + this.linkRate * -1.9770147E-05f * num;
					float num3 = 4.232986E-09f;
					float num4 = -0.010038247f + this.linkRate * 1.9769608E-05f * num;
					float num5 = 0f;
					float num6 = this.linkRate * -1.1474898f + 0.5930886f * num;
					float num7 = 0f;
					this.linkBone.localPosition = new Vector3(num2, num3, num4);
					this.linkBone.localEulerAngles = new Vector3(num5, num6, num7);
				}
			}
			public float Normalize(float rot, float criteria = 180f)
			{
				if (rot >= criteria) return -1f * (360f - rot);
				return rot;
			}
			public Transform baseBone;
			public Transform linkBone;
			public float linkRate = 1f;
			public Action DoUpdate;
			public enum LinkRotationType
			{
				DEFAULT,
				ARM01_DAM,
				ARMLOW01_ELBO_DAM,
				ARMLOW02_DAM,
				WRIST_DAM
			}
		}
	}
}
